package org.openea.eap.module.obpm.service.form.generator;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.jsoup.nodes.Element;
import org.openbpm.base.api.exception.BusinessException;
import org.openbpm.base.core.util.StringUtil;
import org.openbpm.base.core.util.ThreadMapUtil;
import org.openbpm.bus.api.constant.BusTableRelType;
import org.openbpm.bus.api.model.IBusTableRel;
import org.openbpm.bus.api.model.IBusinessColumn;
import org.openea.eap.module.obpm.model.form.design.FormColumn;
import org.openea.eap.module.obpm.model.form.design.FormGroup;
import org.springframework.stereotype.Component;


@Component
public class VueFormElementGenerator
        extends AbsFormElementGenerator {
    private void handleVModel(Element element, IBusinessColumn column) {
        handleElementPlaceHolder(column, element);

        String boCode = (String) ThreadMapUtil.get("boCode");
        IBusTableRel relation = (IBusTableRel) ThreadMapUtil.get("relation");

        if (relation.getType().equals(BusTableRelType.ONE_TO_MANY.getKey())) {
            element.attr("v-model", column.getTable().getKey() + "." + column.getKey());

            return;
        }
        element.attr("v-model", getScopePath(relation) + "." + column.getKey());
    }

    @Override
    protected String getColumnOnetext(IBusinessColumn column) {
        Element element = getElement("input").attr("type", "text").addClass("form-control");

        handleVModel(element, column);
        handlePermission(element, column);
        handleValidateRules(element, column);

        return element.toString();
    }

    @Override
    protected String getColumnDate(IBusinessColumn column) {
        Element element = getElement("ab-date").attr("type", "text").addClass("form-control");

        handleVModel(element, column);
        handlePermission(element, column);
        handleValidateRules(element, column);

        String configStr = column.getCtrl().getConfig();
        if (StringUtil.isEmpty(configStr)) {
            throw new BusinessException(String.format("表【%s】日期字段  【%s】解析失败,配置信息不能为空", new Object[]{column.getTable().getKey(), column.getComment()}));
        }

        String format = JSON.parseObject(configStr).getString("format");

        element.attr("format", format);

        return element.toString();
    }

    @Override
    protected String getColumnDic(IBusinessColumn column) {
        Element element = getElement("ab-dict").attr("type", "text").addClass("input-div");

        handleVModel(element, column);
        handlePermission(element, column);
        handleValidateRules(element, column);

        JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
        if (!config.containsKey("key")) {
            throw new BusinessException(String.format("表【%s】数据字典  字段【%s】解析失败,alias 配置信息不能为空", new Object[]{column.getTable().getKey(), column.getComment()}));
        }

        element.attr("dict-key", config.getString("key"));

        return element.toString();
    }

    @Override
    protected String getColumnIdentity(IBusinessColumn column) {
        Element element = getElement("ab-serial-no").attr("type", "text").addClass("form-control");
        handleVModel(element, column);
        element.attr("v-bind:ab-permission", getPermissionPath(column));
        handleValidateRules(element, column);

        JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
        if (!config.containsKey("alias")) {
            throw new BusinessException(String.format("表【%s】流水号  字段【%s】解析失败,alias 配置信息不能为空", new Object[]{column.getTable().getKey(), column.getComment()}));
        }
        element.attr("serial-no", config.getString("alias"));

        return element.toString();
    }

    @Override
    protected String getColumnMultitext(IBusinessColumn column) {
        Element element = getElement("textarea").attr("type", "text").addClass("form-control");

        handleVModel(element, column);
        handlePermission(element, column);
        handleValidateRules(element, column);

        return element.toString();
    }

    @Override
    protected String getColumnJson(IBusinessColumn column) {
        return getColumnMultitext(column);
    }

    @Override
    protected String getColumnCheckBox(IBusinessColumn column) {
        JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
        if (!config.containsKey("options")) {
            throw new BusinessException(String.format("表【%s】CheckBox 字段  【%s】解析失败,options 配置信息不能为空", new Object[]{column.getTable().getKey(), column.getComment()}));
        }

        Element checkbox = getElement("ab-checkbox");
        handleVModel(checkbox, column);
        handlePermission(checkbox, column);
        handleValidateRules(checkbox, column);
        Element template = checkbox.appendElement("div").attr("slot-scope", "checkboxScope");

        JSONArray options = config.getJSONArray("options");
        for (int i = 0; i < options.size(); i++) {
            JSONObject option = options.getJSONObject(i);

            Element element = template.appendElement("label").addClass("checkbox-inline");
            Element child = element.appendElement("input").attr("type", "checkbox");
            child.attr("v-model", "checkboxScope.tempData.currentValue");
            child.attr("value", option.getString("key"));
            child.attr("name", String.format("%s-%s-%s", new Object[]{ThreadMapUtil.get("boCode"), column.getTable().getKey(), column.getName()}));
            handlePermission(child, column);
            element.appendText(option.getString("txt"));
        }

        return checkbox.toString();
    }

    @Override
    protected String getColumnRadio(IBusinessColumn column) {
        JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
        if (!config.containsKey("options")) {
            throw new BusinessException(String.format("表【%s】Radio 字段  【%s】解析失败,options 配置信息不能为空", new Object[]{column.getTable().getKey(), column.getComment()}));
        }

        Element permissionElement = getElement("div");
        JSONArray options = config.getJSONArray("options");
        for (int i = 0; i < options.size(); i++) {
            JSONObject option = options.getJSONObject(i);

            Element label = permissionElement.appendElement("label").addClass("radio-inline");
            Element child = label.appendElement("input").attr("type", "radio");

            handleVModel(child, column);
            child.attr("v-ab-permission", getPermissionPath(column));
            handleValidateRules(child, column);

            child.attr("value", option.getString("key"));
            label.appendText(option.getString("txt"));
        }

        return permissionElement.toString();
    }

    @Override
    protected String getColumnSelect(IBusinessColumn column, Boolean isMultiple) {
        JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
        if (!config.containsKey("options")) {
            throw new BusinessException(String.format("表【%s】Select 字段  【%s】解析失败,options 配置信息不能为空", new Object[]{column.getTable().getKey(), column.getComment()}));
        }

        Element permissionElement = getElement("select").addClass("form-control");
        handleVModel(permissionElement, column);
        permissionElement.attr("v-ab-permission", getPermissionPath(column));
        handleValidateRules(permissionElement, column);

        if (isMultiple.booleanValue()) {
            permissionElement.attr("multiple", "true");
        }

        Element select = permissionElement.appendElement("option");
        select.attr("value", "");
        select.text("请选择");

        JSONArray options = config.getJSONArray("options");
        for (int i = 0; i < options.size(); i++) {
            JSONObject option = options.getJSONObject(i);

            Element element = permissionElement.appendElement("option");
            element.attr("value", option.getString("key"));
            element.text(option.getString("txt"));
        }

        return permissionElement.toString();
    }

    @Override
    protected String getColumnFile(IBusinessColumn column) {
        Element element = getElement("ab-upload").attr("href", "javascript:void(0)").addClass("btn btn-primary fa-upload");
        handleVModel(element, column);
        element.attr(":ab-permission", getPermissionPath(column));

        IBusTableRel relation = (IBusTableRel) ThreadMapUtil.get("relation");

        element.attr("desc", relation.getTableComment() + "-" + column.getComment());
        return element.toString();
    }

    @Override
    protected String getColumnPic(IBusinessColumn column){
        // 单图
        Element element = getElement("ab-single-image");
        handleVModel(element, column);
        if(column.getCtrl()!=null && StringUtil.isNotEmpty(column.getCtrl().getConfig())){
            JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
            if(config.containsKey("ewidth")){
                element.attr(":outerwidth", ""+config.getInteger("ewidth"));
            }
            if(config.containsKey("eheight")){
                element.attr(":outerheight", ""+config.getInteger("eheight"));
            }
        }
        element.attr(":ab-permission", getPermissionPath(column));
        handleValidateRules(element, column);
        return element.toString();
    }

    @Override
    protected String getColumnMPic(IBusinessColumn column){
        // 多图，默认同文件
        Element element = getElement("ab-mult-image");
        handleVModel(element, column);
        if(column.getCtrl()!=null && StringUtil.isNotEmpty(column.getCtrl().getConfig())){
            JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
            if(config.containsKey("ewidth")){
                element.attr(":outerwidth", ""+config.getInteger("ewidth"));
            }
            if(config.containsKey("eheight")){
                element.attr(":outerheight", ""+config.getInteger("eheight"));
            }

            // minCount/maxCount
            if(config.containsKey("minCount")){
                element.attr(":minCount", ""+config.getInteger("minCount"));
            }
            if(config.containsKey("maxCount")){
                element.attr(":maxCount", ""+config.getInteger("maxCount"));
            }

        }
        element.attr(":ab-permission", getPermissionPath(column));
        handleValidateRules(element, column);

        return element.toString();
    }

    @Override
    public String getSubAttrs(IBusTableRel rel) {
        StringBuilder sb = new StringBuilder();
        sb.append(" id=\"" + rel.getBusObj().getKey() + "-" + rel.getTableKey() + "\" ");


        if (rel.getType().equals(BusTableRelType.ONE_TO_MANY.getKey()) && !rel.getParent().getType().equals(BusTableRelType.MAIN.getKey())) {
            sb.append(" hide ");
        }

        sb.append(" table-key=\"" + rel.getTableKey() + "\" ");
        return sb.toString();
    }

    @Override
    protected void handlePermission(Element element, IBusinessColumn column) {
        element.attr("v-ab-permission", getPermissionPath(column));
    }

    @Override
    protected void handleValidateRules(Element element, IBusinessColumn column) {
        super.handleValidateRules(element, column);

        element.attr("v-ab-validate", element.attr("ab-validate"));
        element.removeAttr("ab-validate");
    }

    @Override
    public String getGeneratorName() {
        return "vueGenerator";
    }

    @Override
    public String getScopePath(IBusTableRel relation) {
        if (relation.getType().equals(BusTableRelType.MAIN.getKey())) {
            return "data." + relation.getBusObj().getKey();
        }

        StringBuilder sb = new StringBuilder();

        sb.append(relation.getTableKey());

        if (relation.getType().equals(BusTableRelType.ONE_TO_MANY.getKey())) {
            sb.append("List");

            if (isThreeChildren(relation)) {
                sb.insert(0, "subTempData." + relation.getParent().getTableKey() + ".");
                return sb.toString();
            }
        }


        getParentPath(relation.getParent(), sb);

        return sb.toString();
    }

    @Override
    protected String getPermissionPath(IBusinessColumn column) {
        String boCode = (String) ThreadMapUtil.get("boCode");
        IBusTableRel relation = (IBusTableRel) ThreadMapUtil.get("relation");
        boolean isLine = ((Boolean) ThreadMapUtil.getOrDefault("isLine", Boolean.valueOf(false))).booleanValue();
        if (!isLine && relation.getType().equals(BusTableRelType.ONE_TO_MANY.getKey())) {
            return "scope.permission." + boCode + "." + column.getTable().getKey() + "." + column.getKey();
        }
        return "permission." + boCode + "." + column.getTable().getKey() + "." + column.getKey();
    }


    public String getLineColumn(IBusinessColumn column, IBusTableRel relation) {
        ThreadMapUtil.put("isLine", Boolean.valueOf(true));
        String str = getColumn(column, relation);
        ThreadMapUtil.remove("isLine");
        return str;
    }

    public String getLineColumn(FormGroup group, FormColumn formColumn) {
        IBusTableRel tableRel = group.getTableRelation();


        if (StringUtil.isNotEmpty(formColumn.getTableKey()) && !formColumn.getTableKey().equals(tableRel.getTableKey())) {
            IBusTableRel table = tableRel.find(formColumn.getTableKey());
            if (table != null) {
                tableRel = table;
            }
        }

        if (!formColumn.getTableKey().equals(tableRel.getTableKey())) {
            this.LOG.error("生成表单可能存在异常！formColumnTableKey{},tableRelTableKey{}", formColumn.getTableKey(), tableRel.getTableKey());
        }

        IBusinessColumn businessColumn = tableRel.getTable().getColumnByKey(formColumn.getKey());

        if (businessColumn == null) {
            this.LOG.error("布局模板查找Column配置失败！字段：{}，表：{}", formColumn.getComment(), formColumn.getTableKey());
        }

        return getLineColumn(businessColumn, tableRel);
    }


    public String getScopePath_old(IBusTableRel relation) {
        return super.getScopePath(relation);
    }
}
